package com.gxa.employment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxa.employment.common.ManagerThreadLocal;
import com.gxa.employment.entity.dto.PageBean;

import com.gxa.employment.entity.pojo.Permission;
import com.gxa.employment.entity.vo.PageVo;
import com.gxa.employment.mapper.PermissionMapper;
import com.gxa.employment.service.PermissionService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统权限表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-03-25
 */
@Service
@Transactional(rollbackFor = Throwable.class)
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    RedisTemplate<String, Object> redisTemplate;
    /**
     * 获取所有指定类型的权限列表
     *
     * @param type 权限类型
     * @return 包含所有指定类型权限的列表
     */
    public List<Permission> getAllPermission(String type) {
        LambdaQueryWrapper<Permission> lambdaQuery = Wrappers.lambdaQuery(Permission.class);
        lambdaQuery.eq(Permission::getPermType, type);
        return setChildren(list(lambdaQuery));
    }

    /**
     * 获取菜单列表
     *
     * @return 菜单列表
     */
    public List<Permission> getMenuList() {
         List<Permission> list = permissionMapper.selectMenuById(ManagerThreadLocal.get().getManagerId());
        return setChildren(list);
    }

    /**
     * 删除所有权限。
     *
     * @param id 权限的ID
     */
    @Override
    public void deleteAllPermission(Integer id) {
        //查询子级   只能查询一层子级  如果要查询多层子级 需要递归查询
        List<Integer> list = permissionMapper.selectChildId(id);
        list.add(id);
        //删除权限
        permissionMapper.batchDelete(list);
        //删除角色权限关联
        permissionMapper.batchDeleteByRole(list);
        //删除redis
        Set<String> keys = redisTemplate.keys("role:*");
        if (keys != null) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * 通过分页条件获取权限信息
     *
     * @param pageBean 分页参数
     * @return 包含权限信息的分页对象
     */
    @Override
    public PageVo<Permission> getByPage(PageBean pageBean) {
        LambdaQueryWrapper<Permission> lambdaQuery = Wrappers.lambdaQuery(Permission.class);
        lambdaQuery
                .like(StringUtils.isNotEmpty(pageBean.getName()), Permission::getPermName, pageBean.getName())
                .or()
                .like(StringUtils.isNotEmpty(pageBean.getName()), Permission::getPermRemark, pageBean.getName())
                .orderByDesc(Permission::getPermId);
        IPage<Permission> page = new Page<>(pageBean.getPage(), pageBean.getSize());
        page(page, lambdaQuery);
        return new PageVo<>(page.getTotal(), page.getRecords());
    }

    /**
     * 根据类型返回权限
     *
     * @param list 权限集合
     * @return 权限列表，如果没有权限则返回null
     */
    public List<Permission> setChildren(List<Permission> list) {
        if (list.isEmpty()) return null;
        //获取总数
        Integer total = list.size();
        //统计数量
        Integer number = 0;

        //父级列表
        List<Permission> rootList = list.stream().filter((perm) -> perm.getPermPid() == 0).collect(Collectors.toList());
        //其他列表
        List<Permission> otherList = list.stream().filter((perm) -> perm.getPermPid() != 0).collect(Collectors.toList());
        if (otherList.isEmpty()) return rootList;

        //父级总数
        number += rootList.size();
        List<Permission> pList = rootList;
        //二级列表
        while (true) {
            List<Permission> tempPList = new ArrayList<>();
            //循环变量添加子级
            for (Permission permission : pList) {
                //使用for/forEach会出现  并发修改异常
                for (int j = 0; j < otherList.size(); ) {
                    //添加子级
                    if (permission.getPermId().equals(otherList.get(j).getPermPid())) {
                        //添加到父级中
                        permission.getChildren().add(otherList.get(j));
                        //储存本次添加的数据，作为下次的父级
                        tempPList.add(otherList.get(j));
                        //排除已经找到位置的
                        otherList.remove(otherList.get(j));
                        number++;
                        continue;
                    }
                    //改变了 otherList 的大小，所以循环需要重置j的值，否则会跳过一些数据
                    j++;
                }
            }
            //如果全部都遍历完
            if (number.equals(total)) {
                return rootList;
            }
            //再次循环，直到全部都遍历完
            pList = tempPList;
        }
    }
}
